package com.joejag.mavenstats.client.views.forms.project;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.gwtext.client.core.Template;
import com.gwtext.client.data.*;
import com.gwtext.client.widgets.form.*;
import com.gwtext.client.widgets.form.event.FieldListenerAdapter;
import com.joejag.mavenstats.client.dto.ProjectDTO;
import com.joejag.mavenstats.client.service.ParserService;
import com.joejag.mavenstats.client.service.ProjectsService;

import java.util.List;

public abstract class ProjectDTOForm extends Form
{
  protected ComboBox teamNameCombo;
  protected TextField projectURL;
  protected TextField projectName;

  final RecordDef recordDef = new RecordDef(
      new FieldDef[]{
          new StringFieldDef("teamname"),
      }
  );
  final private Store store = new Store(recordDef);
  private final ProjectDTO project;

  public ProjectDTOForm(final ProjectDTO project, String text)
  {
    super(new FormConfig()
    {
      {
        setWidth(600);
        setLabelWidth(140);
      }
    });
    this.project = project;

    this.fieldset(text);

    createLayout(project);

    this.end();
    this.render();
  }

  protected void createProjectNameTextfield(final ProjectDTO project)
  {
    projectName = new TextField(new TextFieldConfig()
    {
      {
        if (project.projectName != null)
          setValue(project.projectName);

        setFieldLabel("Project Name");
        setName("project_name");
        setWidth(175 * 2);
        setAllowBlank(false);
      }
    });
    this.add(projectName);
  }

  protected void createTeamSelectorCombo(final ProjectDTO project)
  {
    setupTeamNames();
    teamNameCombo = new ComboBox(new ComboBoxConfig()
    {
      {
        if (project.teamname != null)
          setValue(project.teamname);

        setFieldLabel("Team Name");
        setName("teamname");
        setWidth((175 * 2) + 17);
        setAllowBlank(false);

        setEmptyText("Select Team Name");

        setMinChars(1);
        setStore(store);
        setTypeAhead(true);
        setDisplayField("teamname");
        setTpl(new Template("<div>{teamname}</div>"));

        setSelectOnFocus(true);

        setMode("local");
        setTriggerAction("all");
      }
    });
    this.add(teamNameCombo);
  }

  protected void createProjectURLtextfield(final ProjectDTO project)
  {
    projectURL = new TextField(new TextFieldConfig()
    {
      {
        if (project.projectURL != null)
          setValue(project.projectURL);

        setFieldLabel("Project.xml URL");
        setName("url");
        setWidth(175 * 2);
        setAllowBlank(false);
      }
    });
    this.add(projectURL);
  }

  protected void addURLtextfieldListener()
  {
    projectName.disable();
    projectURL.addFieldListener(new FieldListenerAdapter()
    {
      public void onValid(Field field)
      {
        super.onValid(field);

        projectName.enable();

        if ((projectURL.getText().equals(project.projectURL)))
          return;

        ParserService.App.getInstance().getProjectName(projectURL.getText(), new AsyncCallback()
        {
          public void onFailure(Throwable throwable)
          {
          }

          public void onSuccess(Object o)
          {
            projectName.setValue(o.toString());
          }
        });
      }
    });
  }

  private void setupTeamNames()
  {
    ProjectsService.App.getInstance().getTeamNames(new AsyncCallback()
    {
      public void onFailure(Throwable throwable)
      {
      }

      public void onSuccess(Object o)
      {
        setAutocomplete((List) o);
      }
    });
  }

  private void setAutocomplete(List teamNames)
  {
    for (int i = 0; i < teamNames.size(); i++)
    {
      Record record = recordDef.createRecord(new Object[]{teamNames.get(i)});
      store.add(record);
    }
    store.commitChanges();
  }

  public ProjectDTO getProject()
  {
    ProjectDTO dto = new ProjectDTO(projectURL.getText(), teamNameCombo.getRawValue(), projectName.getText());
    setupTeamNames();
    return dto;
  }

  public abstract String getText();
  public abstract void performSomeAction(ProjectDTO project);
  protected abstract void createLayout(ProjectDTO project);
}